#include "Avalon/IOTests/BufferReaderTester.hpp"
#include "Avalon/IO/Buffer.hpp"
#include "Avalon/IO/BufferReader.hpp"
#include "Avalon/IO/EndOfFileException.hpp"

using namespace Avalon;
using namespace Avalon::IO;
using namespace Avalon::IO::Tests;
using namespace Avalon::Threading;
using namespace boost;
using namespace std;

void BufferReaderTester::TestCreateEmpty() {
  BufferReader reader(BufferFromString(""));
  Async<int> readResult;
  Buffer buffer;
  reader.Read(&buffer, Store(readResult));
  CPPUNIT_ASSERT_THROW(readResult.Get(), EndOfFileException);
}

void BufferReaderTester::TestRead() {
  string message = "hello world";
  BufferReader reader(BufferFromString(message));
  Async<int> readResult;
  Buffer data;
  reader.Read(&data, Store(readResult));
  CPPUNIT_ASSERT(readResult.Get() == message.size());
  CPPUNIT_ASSERT(strncmp(data.GetData(), message.c_str(),
    message.size()) == 0);
}

void BufferReaderTester::TestReadSomeToBuffer() {
  string message = "hello world";
  BufferReader reader(BufferFromString(message));
  Async<int> readResult;
  Buffer data;
  reader.Read(&data, 6, Store(readResult));
  CPPUNIT_ASSERT(readResult.Get() == 6);
  CPPUNIT_ASSERT(strncmp(data.GetData(), "hello ", 6) == 0);
  readResult.Reset();
  data.Reset();
  reader.Read(&data, 5, Store(readResult));
  CPPUNIT_ASSERT(readResult.Get() == 5);
  CPPUNIT_ASSERT(strncmp(data.GetData(), "world", 5) == 0);
}

void BufferReaderTester::TestReadSomeToPointer() {
  string message = "hello world";
  BufferReader reader(BufferFromString(message));
  Async<int> readResult;
  scoped_array<char> data(new char[message.size()]);
  reader.Read(data.get(), 6, Store(readResult));
  CPPUNIT_ASSERT(readResult.Get() == 6);
  CPPUNIT_ASSERT(strncmp(data.get(), "hello ", 6) == 0);
  readResult.Reset();
  reader.Read(data.get(), 5, Store(readResult));
  CPPUNIT_ASSERT(readResult.Get() == 5);
  CPPUNIT_ASSERT(strncmp(data.get(), "world", 5) == 0);
}
